#include <cstdio>
#include <iostream>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
#define MAX_N 400

bool visited[MAX_N][MAX_N];
int mt[MAX_N][MAX_N];
struct node
{
    int x,y;
    int h;

    node(int xx,int yy,int hh):x(xx),y(yy),h(hh){}
};

struct cmp
{
    bool operator()(const node &a, const node &b)
    {
        return a.h > b.h;
    }
};

priority_queue<node,vector<node>, cmp> que;
int m,n;
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};

int main()
{
   // freopen("2227.txt","r",stdin);
    scanf("%d%d",&m,&n);
    int h;
    memset(visited,0,sizeof(visited));
    for (int i =  1;  i <= n; i++)
    {
        for (int j = 1 ; j<=m ; j++)
        {
            scanf("%d",&mt[i][j]);
            if (i==1 || i == n || j==1 || j == m) {
                visited[i][j] = 1;
                que.push(node(i,j,mt[i][j]));
            }
        }
    }
    int tx,ty;
    int ans = 0;
    while (!que.empty()){
        node top = que.top();
        que.pop();
        for (int d = 0 ;  d < 4 ; d++){
            tx = top.x + dx[d];
            ty = top.y + dy[d];
            if (1<=tx && tx <= n && 1 <= ty && ty <= m){
                if (!visited[tx][ty]) {
                    if (top.h > mt[tx][ty]){
                        ans += top.h - mt[tx][ty];
                        que.push(node(tx,ty,top.h));
                    }else {
                        que.push(node(tx,ty,mt[tx][ty]));
                    }
                    visited[tx][ty] = 1;
                }
            }
         }
    }

    cout << ans << endl;

    return 0;
}
